import { Request, Response, NextFunction } from 'express'
import { getUserByName, getUserById } from './user.service'
import bcrypt from 'bcrypt'
import _ from 'lodash'

export const validateUser = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  const { name, password } = req.body

  if (!name || !password) {
    return next(new Error('USER_NAME_OR_PASSWORD_IS_EMPTY'))
  }

  const { id } = await getUserByName(name)
  if (id) return next(new Error('USER_ALREADY_EXISTS'))

  next()
}

export const hashPassword = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  const { password } = req.body

  req.body.password = await bcrypt.hash(password, 10)
  next()
}

export const validateUpdateUserData = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  const { validate, update } = req.body
  const { id: userId } = req.user

  try {
    if (!_.has(validate, 'password')) {
      return next(new Error('PASSWORD_IS_REQUIRED'))
    }
    const user = await getUserById(userId, { password: true })
    const matched = await bcrypt.compare(validate.password, user.password)

    if (!matched) {
      return next(new Error('PASSWORD_IS_INCORRECT'))
    }

    if (update.name) {
      const user = await getUserByName(update.name)

      if (user) {
        return next(new Error('USER_ALREADY_EXISTS'))
      }
    }

    if (update.password) {
      const matched = await bcrypt.compare(update.password, user.password)

      if (matched) {
        return next(new Error('PASSWORD_IS_THE_SAME'))
      }

      req.body.update.password = await bcrypt.hash(update.password, 10)
    }
  } catch (error) {
    return next(error)
  }

  next()
}
